<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Props Management</title>
    <link rel="stylesheet" href="./css/index.css">
    <script src="./js/vue.global.js"></script>
    <script src="./js/axios.min.js"></script>
</head>
<body>
<div id="app">
    <div class="container">
        <div class="header">
            <h1>🚀 Props Management</h1>
            <p>Spring Boot 配置文件管理系统 - 支持可视化编辑和版本管理</p>

            <!-- 缓存状态警告条 -->
            <div v-if="showCacheWarning && totalCacheCount > 0" class="cache-warning">
                <div class="cache-warning-content">
                    <span class="cache-warning-icon">💾</span>
                    <span class="cache-warning-text">
                            检测到 {{ totalCacheCount }} 项缓存的配置修改，刷新页面后仍然保留
                        </span>
                    <button class="btn btn-outline btn-sm" @click="clearAllCache">
                        🗑️ 清空所有缓存
                    </button>
                    <button class="btn btn-outline btn-sm" @click="showCacheWarning = false">
                        ✕ 关闭
                    </button>
                </div>
            </div>
        </div>

        <div class="main-content">
            <div class="sidebar">
                <div class="sidebar-header">
                    📁 配置文件列表 ({{ files.length }} 个文件)
                </div>
                <div v-if="files.length === 0" class="empty-state" style="padding: 20px; text-align: center;">
                    <p>{{ loading ? '加载中...' : '未找到配置文件' }}</p>
                </div>
                <div class="file-list">
                    <div v-for="file in files"
                         :key="file.fileName"
                         :class="['file-item', { active: selectedFile?.fileName === file.fileName }]"
                         @click="selectFile(file)">
                        <div :class="['file-icon', file.fileType]">
                            {{ file.fileType === 'properties' ? 'P' : 'Y' }}
                        </div>
                        <div>
                            <div style="font-weight: 500;">{{ file.fileName }}</div>
                            <div style="font-size: 11px; opacity: 0.7;">{{ formatFileSize(file.fileSize) }}</div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="content-area">
                <div v-if="!selectedFile" class="empty-state">
                    <h3>选择一个配置文件</h3>
                    <p>从左侧列表中选择一个配置文件来查看和编辑其内容</p>
                </div>

                <div v-else>
                    <div class="content-header">
                        <div class="content-title">
                            {{ selectedFile.fileName }}
                            <span v-if="getModifiedCount() > 0" class="modified-indicator" style="margin-left: 10px;">
                                    ⚠️ {{ getModifiedCount() }} 项已修改
                                </span>
                            <span v-if="currentFileCacheCount > 0" class="cache-indicator" style="margin-left: 10px;"
                                  title="当前文件有缓存的配置修改">
                                    💾 {{ currentFileCacheCount }} 项缓存
                                </span>
                        </div>
                        <div class="action-buttons">
                            <button v-if="currentFileCacheCount > 0"
                                    class="btn btn-warning"
                                    @click="clearFileCache(selectedFile.fileName)"
                                    title="清空当前文件的缓存">
                                🗑️ 清空缓存
                            </button>
                            <button class="btn btn-primary" @click="showVersions">
                                📚 查看版本
                            </button>
                            <button class="btn btn-success" @click="showSaveModal">
                                💾 保存版本
                            </button>
                        </div>
                    </div>

                    <div v-if="loading" class="loading">
                        加载中...
                    </div>

                    <div v-else-if="selectedFile" class="table-container">
                        <table class="config-table" ref="configTable">
                            <thead>
                            <tr>
                                <th class="resizable col-key" data-column="key">
                                    📋 配置项
                                </th>
                                <th class="resizable col-value" data-column="value">
                                    🔧 当前值
                                </th>
                                <th class="col-action">
                                    ⚡ 操作
                                </th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr v-for="(value, key) in selectedFile.configs"
                                :key="key"
                                :class="['config-row', { 'modified': isConfigModified(key), 'cached': isConfigCached(key) }]">
                                <td class="config-key">
                                    <span v-if="!isConfigEditable(key)" style="color: #e74c3c; margin-right: 5px;"
                                          title="启动时配置，不可运行时修改">🔒</span>
                                    <span v-if="isConfigCached(key)" class="cache-indicator-small"
                                          title="配置已缓存">💾</span>
                                    <span v-if="isConfigModified(key)" class="change-tooltip">
                                                <span class="modified-indicator" title="已修改，尚未保存版本">⚠️</span>
                                                <div class="tooltip-content" style="margin-left: 40px;">
                                                    <div class="tooltip-label">配置项已修改：</div>
                                                    <div class="tooltip-old">原值: {{ getOriginalValue(key) }}</div>
                                                    <div class="tooltip-new">新值: {{ value }}</div>
                                                </div>
                                            </span>
                                    {{ key }}
                                </td>
                                <td class="config-value">
                                            <textarea
                                                    v-if="editingKey === key"
                                                    v-model="editingValue"
                                                    @keyup.enter.ctrl="saveConfigValue(key, editingValue)"
                                                    @keyup.esc="cancelEdit"
                                                    class="value-input"
                                                    ref="editInput"
                                                    :rows="Math.max(1, Math.ceil(editingValue.length / 50))">
                                            </textarea>
                                    <div v-else :class="['value-display', { 'readonly': !isConfigEditable(key) }]">
                                        {{ value }}
                                    </div>
                                </td>
                                <td>
                                    <button
                                            v-if="editingKey === key"
                                            @click="saveConfigValue(key, editingValue)"
                                            class="btn btn-success"
                                            style="font-size: 12px; padding: 4px 8px; margin-right: 5px;">
                                        ✅ 保存
                                    </button>
                                    <button
                                            v-if="editingKey === key"
                                            @click="cancelEdit"
                                            class="btn btn-danger"
                                            style="font-size: 12px; padding: 4px 8px;">
                                        ❌ 取消
                                    </button>
                                    <button
                                            v-else-if="isConfigEditable(key)"
                                            @click="startEdit(key)"
                                            class="btn btn-primary"
                                            style="font-size: 12px; padding: 4px 8px;">
                                        ✏️ 编辑
                                    </button>
                                    <button
                                            v-else
                                            disabled
                                            class="btn btn-disabled"
                                            style="font-size: 12px; padding: 4px 8px;"
                                            title="启动时配置，不可运行时修改">
                                        🔒 锁定
                                    </button>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 保存版本模态框 -->
    <div :class="['modal', { show: showSaveModalFlag }]">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title">💾 保存配置版本</h3>
            </div>
            <div class="form-group">
                <label class="form-label">保存说明</label>
                <textarea
                        v-model="saveComment"
                        class="form-input"
                        rows="3"
                        placeholder="请输入保存说明..."></textarea>
            </div>
            <div class="modal-actions">
                <button class="btn" @click="hideSaveModal">取消</button>
                <button class="btn btn-success" @click="saveVersion">保存</button>
            </div>
        </div>
    </div>

    <!-- 版本列表模态框 -->
    <div :class="['modal', { show: showVersionsModalFlag }]">
        <div class="modal-content" style="max-width: 700px;">
            <div class="modal-header">
                <h3 class="modal-title">📚 版本历史 - {{ selectedFile?.fileName }}</h3>
            </div>
            <div class="version-list">
                <div v-if="versions.length === 0" class="empty-state">
                    <p>暂无版本记录</p>
                </div>
                <div v-for="version in versions" :key="version.versionId" class="version-item">
                    <div class="version-info">
                        <div class="version-number">📌 版本 {{ version.versionNumber }}</div>
                        <div class="version-comment">{{ version.comment }}</div>
                        <div class="version-time">🕒 {{ formatDateTime(version.createTime) }}</div>
                    </div>
                    <div>
                        <button
                                class="btn btn-primary"
                                style="font-size: 12px; padding: 4px 8px; margin-right: 5px;"
                                @click="viewVersionContent(version.versionId)">
                            👁️ 查看
                        </button>
                        <button
                                class="btn btn-danger"
                                style="font-size: 12px; padding: 4px 8px;"
                                @click="deleteVersion(version.versionId)">
                            🗑️ 删除
                        </button>
                    </div>
                </div>
            </div>
            <div class="modal-actions">
                <button class="btn" @click="hideVersionsModal">关闭</button>
            </div>
        </div>
    </div>

    <!-- Toast 通知 -->
    <div :class="['toast', toastType, { show: showToast }]">
        {{ toastMessage }}
    </div>

    <!-- 列宽调整提示 -->
    <div :class="['resize-hint', { show: showResizeHint }]">
        💡 拖拽列边界调整宽度，双击恢复默认
    </div>
</div>

<script>
    const {createApp} = Vue;

    createApp({
        data() {
            return {
                files: [],
                selectedFile: null,
                editingKey: null,
                editingValue: '',
                showSaveModalFlag: false,
                saveComment: '',
                showVersionsModalFlag: false,
                versions: [],
                loading: false,
                cachedConfigs: {},
                showCacheWarning: true,

                // API Base URL - 动态获取管理路径
                apiBaseUrl: ''
            };
        },
        computed: {
            // 获取当前文件的缓存数量
            currentFileCacheCount() {
                if (!this.selectedFile) return 0;
                const cached = this.cachedConfigs[this.selectedFile.fileName] || {};
                return Object.keys(cached).length;
            },

            // 获取总缓存数量
            totalCacheCount() {
                let total = 0;
                Object.values(this.cachedConfigs).forEach(fileCache => {
                    total += Object.keys(fileCache).length;
                });
                return total;
            }
        },
        methods: {
            /**
             * 动态获取API基础URL
             */
            getApiBaseUrl() {
                const currentPath = window.location.pathname;
                let managementPath = '/props-management';

                // 从当前路径中提取管理路径
                // 当前路径格式: /demo/props-management/index.html 或 /props-management/index.html
                if (currentPath.includes('/props-management')) {
                    const index = currentPath.indexOf('/props-management');
                    managementPath = currentPath.substring(0, index + '/props-management'.length);
                }

                console.log('Current path:', currentPath);
                console.log('Management path:', managementPath);
                console.log('API base URL:', '/api' + managementPath);

                return '/api' + managementPath;
            },

            async loadFiles() {
                this.loading = true;
                console.log('Loading files from:', `${this.apiBaseUrl}/files`);
                try {
                    const response = await axios.get(`${this.apiBaseUrl}/files`);
                    console.log('Files response:', response.data);
                    if (response.data.success) {
                        this.files = response.data.data;
                        console.log('Files loaded successfully:', this.files);
                    } else {
                        console.error('Files loading failed:', response.data);
                        this.showToast('Failed to load files', 'error');
                    }
                } catch (error) {
                    console.error('Error loading files:', error);
                    this.showToast('Error loading files', 'error');
                } finally {
                    this.loading = false;
                }
            },

            async loadFileDetail(file) {
                try {
                    const response = await axios.get(`${this.apiBaseUrl}/files/${file.fileName}`);
                    console.log('File detail response:', response.data);

                    this.selectedFile = {
                        ...response.data,
                        configs: response.data.content, // 映射 content 到 configs
                        lastVersionContent: response.data.lastVersionContent || {}
                    };

                    console.log('Selected file set to:', this.selectedFile);

                    // 应用缓存的配置
                    this.applyCachedConfigs();

                } catch (error) {
                    console.error('Error loading file detail:', error);
                    this.showToast('Error loading file detail', 'error');
                }
            },

            startEdit(key) {
                // 检查是否为只读配置
                if (this.selectedFile.editableFlags && this.selectedFile.editableFlags[key] === false) {
                    this.showToast('此配置为启动时配置，无法在运行时修改 🔒', 'error');
                    return;
                }

                this.editingKey = key;
                this.editingValue = this.selectedFile.configs[key];
            },

            async saveConfigValue(key, value) {
                if (!this.selectedFile) return;

                try {
                    console.log('Saving config value:', {key, value});

                    const response = await axios.post(`${this.apiBaseUrl}/files/${this.selectedFile.fileName}/update`, {
                        key: key,
                        value: value
                    });

                    if (response.data.success) {
                        // 更新显示的值
                        this.selectedFile.configs[key] = value;
                        this.editingKey = null;
                        this.editingValue = '';

                        // 如果保存成功，添加到缓存（对比版本值）
                        const versionValue = this.getOriginalValue(key);
                        if (value !== versionValue) {
                            this.addToCache(key, value);
                        } else {
                            this.removeFromCache(key);
                        }

                        this.showToast('配置已保存 ✅', 'success');
                    } else {
                        if (response.data.readOnly) {
                            this.showToast(`🔒 ${response.data.message}`, 'error');
                        } else {
                            this.showToast('保存失败: ' + response.data.message, 'error');
                        }
                    }
                } catch (error) {
                    console.error('Error saving config value:', error);
                    this.showToast('保存配置时出错', 'error');
                }
            },

            async saveVersion() {
                if (!this.saveComment.trim()) {
                    this.showToast('请输入保存备注', 'error');
                    return;
                }

                try {
                    const response = await axios.post(`${this.apiBaseUrl}/files/${this.selectedFile.fileName}/save`, {
                        comment: this.saveComment.trim()
                    });

                    if (response.data.success) {
                        this.showToast('版本保存成功 🎉', 'success');
                        this.showSaveModalFlag = false;
                        this.saveComment = '';

                        // 清除当前文件的缓存
                        this.clearFileCache();

                        // 重新加载文件详情以获取最新的版本内容
                        await this.loadFileDetail(this.selectedFile);
                    } else {
                        this.showToast('保存失败: ' + response.data.message, 'error');
                    }
                } catch (error) {
                    console.error('Error saving version:', error);
                    this.showToast('保存版本时出错', 'error');
                }
            },

            async loadVersions() {
                if (!this.selectedFile) return;

                try {
                    const response = await axios.get(`${this.apiBaseUrl}/files/${this.selectedFile.fileName}/versions`);
                    this.versions = response.data;
                    this.showVersionsModalFlag = true;
                } catch (error) {
                    console.error('Error loading versions:', error);
                    this.showToast('加载版本历史时出错', 'error');
                }
            },

            async viewVersionContent(versionId) {
                try {
                    const response = await axios.get(`${this.apiBaseUrl}/versions/${versionId}/content`);

                    // 创建新窗口显示版本内容
                    const contentWindow = window.open('', '_blank', 'width=800,height=600');
                    contentWindow.document.write(`
                            <html>
                            <head>
                                <title>版本内容 - ${versionId}</title>
                                <meta charset="UTF-8">
                                <style>
                                    body { 
                                        font-family: 'Monaco', 'Menlo', monospace; 
                                        padding: 20px; 
                                        background: #f8f9fa; 
                                    }
                                    .header { 
                                        background: #fff; 
                                        padding: 15px; 
                                        border-radius: 5px; 
                                        margin-bottom: 20px; 
                                        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                                    }
                                    .content { 
                                        background: #fff; 
                                        padding: 15px; 
                                        border-radius: 5px; 
                                        white-space: pre-wrap; 
                                        font-size: 14px; 
                                        line-height: 1.5;
                                        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                                    }
                                </style>
                            </head>
                            <body>
                                <div class="header">
                                    <h3>版本内容查看</h3>
                                    <p><strong>版本ID:</strong> ${versionId}</p>
                                    <p><strong>文件:</strong> ${this.selectedFile.fileName}</p>
                                </div>
                                <div class="content">${Object.entries(response.data).map(([key, value]) => `${key}=${value}`).join('\n')}</div>
                            </body>
                            </html>
                        `);
                    contentWindow.document.close();
                } catch (error) {
                    console.error('Error viewing version content:', error);
                    this.showToast('查看版本内容时出错', 'error');
                }
            },

            async deleteVersion(versionId) {
                if (!confirm('确定要删除这个版本吗？此操作不可撤销。')) {
                    return;
                }

                try {
                    const response = await axios.delete(`${this.apiBaseUrl}/files/${this.selectedFile.fileName}/versions/${versionId}`);

                    if (response.data.success) {
                        this.showToast('版本已删除 🗑️', 'success');
                        // 重新加载版本列表
                        await this.loadVersions();
                    } else {
                        this.showToast('删除失败: ' + response.data.message, 'error');
                    }
                } catch (error) {
                    console.error('Error deleting version:', error);
                    this.showToast('删除版本时出错', 'error');
                }
            },

            // === 缓存管理功能 ===
            loadCachedConfigs() {
                try {
                    const cached = localStorage.getItem('props-management-cache');
                    if (cached) {
                        this.cachedConfigs = JSON.parse(cached);
                        if (this.totalCacheCount > 0) {
                            this.showToast(`🔄 检测到 ${this.totalCacheCount} 项缓存的配置修改`, 'success');
                        }
                    }
                } catch (error) {
                    console.error('加载缓存配置失败:', error);
                    this.cachedConfigs = {};
                }
            },

            saveCachedConfigs() {
                try {
                    localStorage.setItem('props-management-cache', JSON.stringify(this.cachedConfigs));
                } catch (error) {
                    console.error('保存缓存配置失败:', error);
                    this.showToast('❌ 缓存保存失败', 'error');
                }
            },

            addToCache(key, value) {
                if (!this.selectedFile) return;
                const fileName = this.selectedFile.fileName;
                if (!this.cachedConfigs[fileName]) {
                    this.cachedConfigs[fileName] = {};
                }
                this.cachedConfigs[fileName][key] = value;
                this.saveCachedConfigs();
            },

            removeFromCache(key) {
                if (!this.selectedFile) return;
                const fileName = this.selectedFile.fileName;
                if (this.cachedConfigs[fileName]) {
                    delete this.cachedConfigs[fileName][key];
                    if (Object.keys(this.cachedConfigs[fileName]).length === 0) {
                        delete this.cachedConfigs[fileName];
                    }
                    this.saveCachedConfigs();
                }
            },

            clearFileCache() {
                if (!this.selectedFile) return;
                const fileName = this.selectedFile.fileName;
                if (this.cachedConfigs[fileName]) {
                    delete this.cachedConfigs[fileName];
                    this.saveCachedConfigs();
                    this.showToast(`🗑️ 已清空 ${fileName} 的缓存`, 'success');
                }
            },

            clearAllCache() {
                if (this.totalCacheCount === 0) {
                    this.showToast('📭 没有缓存需要清空', 'error');
                    return;
                }

                if (confirm(`确定要清空所有 ${this.totalCacheCount} 项缓存的配置吗？`)) {
                    this.cachedConfigs = {};
                    this.saveCachedConfigs();
                    this.showToast('🗑️ 已清空所有缓存', 'success');
                }
            },

            applyCachedConfigs() {
                if (!this.selectedFile) return;

                const fileName = this.selectedFile.fileName;
                const cached = this.cachedConfigs[fileName];

                if (cached && Object.keys(cached).length > 0) {
                    // 应用缓存的值到当前显示的内容
                    Object.keys(cached).forEach(key => {
                        if (this.selectedFile.configs && this.selectedFile.configs.hasOwnProperty(key)) {
                            this.selectedFile.configs[key] = cached[key];
                        }
                    });
                }
            },

            // === 选择文件 ===
            async selectFile(file) {
                console.log('Selecting file:', file);
                this.selectedFile = null;
                this.editingKey = null;

                // 直接使用文件列表中的数据，无需重新请求
                this.selectedFile = {
                    ...file,
                    configs: file.content, // 映射 content 到 configs
                    lastVersionContent: file.lastVersionContent || {}
                };

                console.log('Selected file:', this.selectedFile);

                // 应用缓存的配置
                this.applyCachedConfigs();
            },

            // === 辅助方法 ===
            isConfigModified(key) {
                if (!this.selectedFile || !this.selectedFile.lastVersionContent) {
                    return false;
                }

                const currentValue = this.selectedFile.configs[key];
                const versionValue = this.selectedFile.lastVersionContent[key];

                if (versionValue === undefined) {
                    return true;
                }

                return String(currentValue) !== String(versionValue);
            },

            getOriginalValue(key) {
                if (!this.selectedFile || !this.selectedFile.lastVersionContent) {
                    return 'N/A';
                }

                const versionValue = this.selectedFile.lastVersionContent[key];
                return versionValue !== undefined ? String(versionValue) : '(新增配置项)';
            },

            isConfigCached(key) {
                if (!this.selectedFile) return false;
                const cached = this.cachedConfigs[this.selectedFile.fileName];
                return cached && cached.hasOwnProperty(key);
            },

            showToast(message, type = 'success') {
                // 创建并显示Toast消息
                const toast = document.createElement('div');
                toast.className = `toast ${type} show`;
                toast.textContent = message;
                document.body.appendChild(toast);

                setTimeout(() => {
                    toast.classList.remove('show');
                    setTimeout(() => {
                        document.body.removeChild(toast);
                    }, 300);
                }, 3000);
            },

            cancelEdit() {
                this.editingKey = null;
                this.editingValue = '';
            },

            formatDateTime(dateString) {
                const date = new Date(dateString);
                return date.toLocaleString('zh-CN');
            },

            // === 界面控制方法 ===
            showSaveModal() {
                this.showSaveModalFlag = true;
            },

            hideSaveModal() {
                this.showSaveModalFlag = false;
                this.saveComment = '';
            },

            showVersions() {
                this.loadVersions();
            },

            hideVersionsModal() {
                this.showVersionsModalFlag = false;
            },

            // === 编辑控制方法 ===
            isConfigEditable(key) {
                if (!this.selectedFile || !this.selectedFile.editableFlags) {
                    console.log('No selectedFile or editableFlags, defaulting to editable for key:', key);
                    return true; // 默认可编辑
                }
                const editable = this.selectedFile.editableFlags[key] !== false;
                console.log(`Key ${key} editable:`, editable);
                return editable;
            },

            // === 数据统计方法 ===
            getModifiedCount() {
                if (!this.selectedFile || !this.selectedFile.configs || !this.selectedFile.lastVersionContent) {
                    return 0;
                }

                let count = 0;
                Object.keys(this.selectedFile.configs).forEach(key => {
                    if (this.isConfigModified(key)) {
                        count++;
                    }
                });

                return count;
            },

            formatFileSize(bytes) {
                if (bytes === 0) return '0 B';
                const k = 1024;
                const sizes = ['B', 'KB', 'MB', 'GB'];
                const i = Math.floor(Math.log(bytes) / Math.log(k));
                return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
            }
        },

        async mounted() {
            // 初始化API基础URL
            this.apiBaseUrl = this.getApiBaseUrl();
            console.log('Vue app mounted, API base URL:', this.apiBaseUrl);

            // 配置 axios 默认设置，确保正确处理 UTF-8 编码
            axios.defaults.headers.common['Accept'] = 'application/json;charset=UTF-8';
            axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
            axios.defaults.responseType = 'json';
            axios.defaults.responseEncoding = 'utf8';

            console.log('Starting to load files...');
            // 加载配置文件
            await this.loadFiles();

            console.log('Loading cached configs...');
            // 加载缓存配置
            this.loadCachedConfigs();

            console.log('Vue app initialization completed');
        }
    }).mount('#app');
</script>
</body>
</html> 